package com.d3works.apps.base.service;

import com.d3works.apps.base.db.DataConfigLine;
import com.d3works.apps.base.db.repo.DataConfigLineRepository;
import com.d3works.apps.base.exceptions.AdminExceptionMessage;
import com.d3works.db.JpaRepository;
import com.d3works.db.Model;
import com.d3works.db.Query;
import com.d3works.db.mapper.Mapper;
import com.d3works.exception.D3worksException;
import com.d3works.exception.db.repo.TraceBackRepository;
import com.d3works.i18n.I18n;
import com.d3works.inject.Beans;
import com.d3works.meta.db.MetaField;
import com.d3works.meta.db.MetaModel;
import com.d3works.meta.db.repo.MetaModelRepository;
import java.util.Locale;
import java.util.ResourceBundle;

public class ObjectDataCommonService {

  private ObjectDataCommonService() {
    throw new IllegalStateException("Utility class");
  }

  public static ResourceBundle getResourceBundle(String language) {

    ResourceBundle bundle;

    if (language == null) {
      bundle = I18n.getBundle();
    } else if (language.equals("fr")) {
      bundle = I18n.getBundle(Locale.FRANCE);
    } else {
      bundle = I18n.getBundle(Locale.ENGLISH);
    }

    return bundle;
  }

  public static String getNameColumn(MetaField field) throws ClassNotFoundException {

    MetaModel metaModel = Beans.get(MetaModelRepository.class).findByName(field.getTypeName());

    return Mapper.of(findModelClass(metaModel)).getNameField().getName();
  }

  public static Class<? extends Model> findModelClass(MetaModel metaModel)
      throws ClassNotFoundException {

    Class<?> modelClass = Class.forName(metaModel.getFullName());

    return (Class<? extends Model>) modelClass;
  }

  public static Query<? extends Model> createQuery(
      Long recordId, DataConfigLine line, Class<? extends Model> modelClass)
      throws D3worksException {

    String filter;
    switch (line.getTypeSelect()) {
      case DataConfigLineRepository.TYPE_PATH:
        MetaField relationalField = line.getMetaFieldPath();
        if (relationalField == null) {
          throw new D3worksException(
              line,
              TraceBackRepository.CATEGORY_NO_VALUE,
              I18n.get(AdminExceptionMessage.EMPTY_RELATIONAL_FIELD_IN_DATA_CONFIG_LINE),
              line.getMetaModel().getName());
        }
        filter = createFilter(relationalField.getName());
        break;

      case DataConfigLineRepository.TYPE_QUERY:
        filter = line.getPath();
        if (filter == null) {
          throw new D3worksException(
              line,
              TraceBackRepository.CATEGORY_NO_VALUE,
              I18n.get(AdminExceptionMessage.EMPTY_QUERY_IN_DATA_CONFIG_LINE),
              line.getMetaModel().getName());
        }
        break;

      default:
        throw new D3worksException(
            line, TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, "Unknown case");
    }

    return JpaRepository.of(modelClass).all().filter(filter, recordId);
  }

  public static String createFilter(String path) {

    if (path == null || path.equals("id")) {
      path = "id";
    } else if (!path.endsWith(".id")) {
      path = path + ".id";
    }

    return "self." + path + " = ?1";
  }
}
